//package cn.bugstack.domain.strategy.service.armory;
//
//import cn.bugstack.domain.strategy.model.entity.StrategyAwardEntity;
//import cn.bugstack.domain.strategy.repository.IStrategyRepository;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Service;
//
//import javax.annotation.Resource;
//import java.math.BigDecimal;
//import java.math.RoundingMode;
//import java.security.SecureRandom;
//import java.util.*;
//import java.util.stream.Collectors;
//import java.util.stream.IntStream;
//
///**
// * @description 策略装配库(兵工厂)，负责初始化策略计算
// * @create 2023-12-23 10:02
// * 后续删除
// */
//@Slf4j
//@Service
//public class StrategyArmory implements IStrategyArmory {
//
//    @Resource
//    private IStrategyRepository strategyRepository;
//
//    /*
//    组装奖品到redis中，按概率分布，概率小的在redis的map中数量多，概率大的在redis的map中数量少
//     */
//    @Override
//    public boolean assembleLotteryStrategy(Long strategyId) {
//        // 1. 查询策略配置
//        List<StrategyAwardEntity> strategyAwardEntities = strategyRepository.queryStrategyAwardList(strategyId);
//
//        // 2. 获取最小概率值
//        BigDecimal minAwardRate = strategyAwardEntities.stream()
//                .map(StrategyAwardEntity::getAwardRate)
//                .min(BigDecimal::compareTo)
//                .orElse(BigDecimal.ZERO);
//
//        // 3. 获取概率值总和
//        BigDecimal totalAwardRate = strategyAwardEntities.stream()
//                .map(StrategyAwardEntity::getAwardRate)
//                .reduce(BigDecimal.ZERO, BigDecimal::add);//reduce意思是减少，在java stream中的api意思更像是聚合，统一，合体，即多个变一个
//
//        // 4. 用 1 % 0.0001 获得概率范围，百分位、千分位、万分位
////        BigDecimal rateRange = totalAwardRate.divide(minAwardRate, 0, RoundingMode.CEILING);//会出现除零异常
//        BigDecimal rateRange=new BigDecimal("0");
//        try {
//            rateRange = totalAwardRate.divide(minAwardRate, 0, RoundingMode.CEILING);//似乎可以不用向上取整
//        }
//        catch (ArithmeticException e){
////            e.printStackTrace();
//            log.debug("出现除零异常，请检查数据");
//        }
//            // 后续操作
//            // 处理除数为零的情况，比如抛出异常或者设置默认值
//
//        // 5. 生成策略奖品概率查找表「这里指需要在list集合中，存放上对应的奖品占位即可，占位越多等于概率越高」
//        List<Integer> strategyAwardSearchRateTables = new ArrayList<>(rateRange.intValue());
//        for (StrategyAwardEntity strategyAward : strategyAwardEntities) {
//            Integer awardId = strategyAward.getAwardId();
//            BigDecimal awardRate = strategyAward.getAwardRate();
//            // 计算出每个概率值需要存放到查找表的数量，循环填充
//            int value = rateRange.multiply(awardRate).setScale(0, RoundingMode.CEILING).intValue();
//            for (int i = 0; i < value; i++) {
//                strategyAwardSearchRateTables.add(awardId);
//            }
//        }
//
//        // 6. 对存储的奖品进行乱序操作
//        Collections.shuffle(strategyAwardSearchRateTables);
//
//        // 7. 生成出Map集合，key值，对应的就是后续的概率值。通过概率来获得对应的奖品ID
////        Map<Integer, Integer> shuffleStrategyAwardSearchRateTable = new LinkedHashMap<>();
////        int len=strategyAwardSearchRateTables.size();
////        for (int i = 0; i < len; i++) {
////            shuffleStrategyAwardSearchRateTable.put(i, strategyAwardSearchRateTables.get(i));
////        }
//
//        // 使用Stream API生成Map集合
//        Map<Integer, Integer> shuffleStrategyAwardSearchRateTable = IntStream.range(0, strategyAwardSearchRateTables.size())
//                .boxed()
//                .collect(Collectors.toMap(i -> i, strategyAwardSearchRateTables::get, (key1, key2) -> key1, LinkedHashMap::new));
//
//        // 8. 存放到 Redis
//        strategyRepository.storeStrategyAwardSearchRateTable(strategyId.toString(), shuffleStrategyAwardSearchRateTable.size(), shuffleStrategyAwardSearchRateTable);
//
//        return true;
//    }
//
//    /*
//    获取随机的数字从redis中抽奖，范围是redis中map的键值对数量
//     */
//    @Override
//    public Integer getRandomAwardId(Long strategyId) {
//        // 分布式部署下，不一定为当前应用做的策略装配。也就是值不一定会保存到本应用，而是分布式应用，所以需要从 Redis 中获取。
//        int rateRange = strategyRepository.getRateRange(strategyId);
//        // 通过生成的随机值，获取概率值奖品查找表的结果
//        return strategyRepository.getStrategyAwardAssemble(String.valueOf(strategyId), new SecureRandom().nextInt(rateRange));
//    }
//}
